package org.orbis.structure.range;

import org.orbis.constants.Constants;

public final class LongRangeTuple{
	private long rangeFrom, rangeTo;
	private int type;

	public static LongRangeTuple greaterThan(long value){
		LongRangeTuple newTuple = new LongRangeTuple();
		newTuple.rangeFrom = value;
		newTuple.rangeTo = Long.MAX_VALUE;
		newTuple.type = Constants.RANGE_GREATER;
		return newTuple;
	}

	public static LongRangeTuple lessThan(long value){
		LongRangeTuple newTuple = new LongRangeTuple();
		newTuple.rangeFrom = Long.MIN_VALUE;
		newTuple.rangeTo = value;
		newTuple.type = Constants.RANGE_LESSOREQUAL;
		return newTuple;
	}

	public static LongRangeTuple equalValue(long value){
		LongRangeTuple newTuple = new LongRangeTuple();
		newTuple.rangeFrom = value;
		newTuple.rangeTo = value;
		newTuple.type = Constants.RANGE_EQUAL;
		return newTuple;
	}

	public static LongRangeTuple notEqualValue(long value){
		LongRangeTuple newTuple = new LongRangeTuple();
		newTuple.rangeFrom = value;
		newTuple.rangeTo = value;
		newTuple.type = Constants.RANGE_NOTEQUAL;
		return newTuple;
	}

	public static LongRangeTuple range(long valueFrom, long valueTo){
		LongRangeTuple newTuple = new LongRangeTuple();
		if(valueFrom < valueTo){
			newTuple.rangeFrom = valueFrom;
			newTuple.rangeTo = valueTo;
		}else {
			newTuple.rangeFrom = valueTo;
			newTuple.rangeTo = valueFrom;
		}
		newTuple.type = Constants.RANGE_RANGE;
		return newTuple;
	}

	public static LongRangeTuple notRange(long valueFrom, long valueTo){
		LongRangeTuple newTuple = new LongRangeTuple();
		if(valueFrom < valueTo){
			newTuple.rangeFrom = valueFrom;
			newTuple.rangeTo = valueTo;
		}else {
			newTuple.rangeFrom = valueTo;
			newTuple.rangeTo = valueFrom;
		}
		newTuple.type = Constants.RANGE_NOTRANGE;
		return newTuple;
	}

	public static LongRangeTuple dontCare(){
		LongRangeTuple newTuple = new LongRangeTuple();
		newTuple.rangeFrom = Long.MIN_VALUE;
		newTuple.rangeTo = Long.MAX_VALUE;
		newTuple.type = Constants.RANGE_DONTCARE;
		return newTuple;
	}
	
	public static LongRangeTuple fromMessage(long rangeFrom, long rangeTo, int type) {
		LongRangeTuple newTuple = new LongRangeTuple();
		newTuple.rangeFrom = rangeFrom;
		newTuple.rangeTo = rangeTo;
		newTuple.type = type;
		return newTuple;
	}

	public boolean isRange(long value){
		switch(this.type){
		case Constants.RANGE_DONTCARE:
			return true;
		case Constants.RANGE_NOTEQUAL:
			return this.rangeFrom != value;
		case Constants.RANGE_NOTRANGE:
			return (value < this.rangeFrom || this.rangeTo < value);
		default:
			return (this.rangeFrom <= value && value <= this.rangeTo);
		}
	}
	
	public long rangeFrom() {
		return rangeFrom;
	}
	
	public long rangeTo() {
		return rangeTo;
	}
	
	public int type() {
		return type;
	}
}
